/*
 * Package il.ac.biu.cs.grossmm.test.test3
 * File SpyPublished.java
 * 
 * This is a part of presence service framework API. 
 * See javadoc for more information.
 *  
 * Copyright (C) 2006 Grossmann Mark
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package il.ac.biu.cs.grossmm.tests.cpptest;

import static il.ac.biu.cs.grossmm.api.data.NodeTypeByInterface.*;
import static il.ac.biu.cs.grossmm.api.keys.KeyFactory.*;
import static il.ac.biu.cs.grossmm.api.keys.PatternFactory.*;
import static il.ac.biu.cs.grossmm.api.presence.BaseVocabulary.*;
import static il.ac.biu.cs.grossmm.api.presence.ResourceType.*;
import il.ac.biu.cs.grossmm.api.OperationFailedException;
import il.ac.biu.cs.grossmm.api.data.Root;
import il.ac.biu.cs.grossmm.api.flow.*;
import il.ac.biu.cs.grossmm.api.keys.Key;
import il.ac.biu.cs.grossmm.api.presence.ResourceType;

import java.util.HashSet;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

public class ProcessorB extends DataProcessorBase implements Notifier<FooPresence>{
	
	static Logger logger = Logger.getLogger("ProcessorB");
	private NotificationPoint<FooPresence> np;
	
	Timer timer = new Timer("ProcessorB-timer");
	
	ConcurrentHashMap<String, Object> set = new ConcurrentHashMap<String, Object>();
	

	public ProcessorB()
	{
		super("Processor B");
		logger.info("Created");
	}

	@Override
	public void run()
	{
		logger.info("Started");
		
		
		np = adm.createNotificationPoint(this, maskPattern(String.class, mandatory(RESOURCE_TYPE, ResourceType.class)), 
			nodeType(FooPresence.class), 0.1);
		
		started();
		
		Random r = new Random();
		while( !mustStop() ) {
			int n = r.nextInt(5000);
			String alice = "Alice"+n;
			
			if(! set.containsKey(alice) )
				continue;
			
			// Key key = key(alice, entry(RESOURCE_TYPE, PRESENCE), entry(WATCHER, null));
			
			Root<FooPresence> fooRoot = (Root<FooPresence>) set.get(alice);
			// Root<FooPresence> fooRoot = np.getNode(key);
			if( fooRoot==null ) {
				System.out.println("oops ");
				continue;
			}
				
			try {
				NodeManipulator man = np.writeLock(fooRoot);
				man.setValue(fooRoot, FooPresence.ENTITY, alice);
				man.setValue(fooRoot, FooPresence.IS_ONLINE, System.currentTimeMillis() % 2 == 0);
				np.writeUnlock(fooRoot);
			} catch( Exception e) {
				e.printStackTrace();
			}
		}
		
		
		timer.cancel();
		
		stopped();
				
		logger.info("Stopped");
	}

	public void fetch(Key key, Track track, Root<FooPresence> node, NodeManipulator manipulator)
	{
		// TODO Implement fetch
		// 
		throw new RuntimeException("Not implemented");
	}

	public boolean subscribe(final Key key, Track track) throws Exception
	{
		//logger.info("key="+key);
		final Root<FooPresence> fooRoot = np.activated(key);
		
		final String alice = (String) key.value();
		
		NodeManipulator man = np.writeLock(fooRoot);
		man.setValue(fooRoot, FooPresence.ENTITY, alice);
		man.setValue(fooRoot, FooPresence.IS_ONLINE, false);
		np.writeUnlock(fooRoot);
		
		set.put(alice, fooRoot);
		
//		final TimerTask notifyTask = new TimerTask() {
//					@Override
//					public void run()
//					{
//						try {
//							NodeManipulator man = np.writeLock(fooRoot);
//							man.setValue(fooRoot, FooPresence.ENTITY, alice);
//							man.setValue(fooRoot, FooPresence.IS_ONLINE, System.currentTimeMillis() % 2 == 0);
//							np.writeUnlock(fooRoot);
//						} catch (OperationFailedException e) {
//							// TODO Auto-generated catch block
//							e.printStackTrace();
//						}
//					}
//				};
//		timer.scheduleAtFixedRate(notifyTask, 300, 300);		
//		
//		timer.schedule(new TimerTask() {
//			@Override
//			public void run()
//			{
//				try {
//					// logger.info("Deactivating...");
//					notifyTask.cancel();
//					
//					np.deactivated(key, Status.FORBIDDEN);
//				} catch (NoSuchSubscription e) {
//					e.printStackTrace();
//				}
//			}
//		}, 60000);
		
		return true;
	}

	public void unsubscribe(Key key)
	{
		// TODO Implement unsubscribe
		// 
		throw new RuntimeException("Not implemented");
	}

}
